package co.gov.medellin.ssti.sub.web.action;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import co.gov.medellin.ssti.sub.common.excepcion.SUBException;
import co.gov.medellin.ssti.sub.common.util.Utility;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.service.AtributosService;
import co.gov.medellin.ssti.sub.model.service.BOTEmpresaService;
import co.gov.medellin.ssti.sub.model.service.BeneficiarioService;
import co.gov.medellin.ssti.sub.model.service.BeneficioService;
import co.gov.medellin.ssti.sub.model.service.EmpresaService;
import co.gov.medellin.ssti.sub.model.service.RenovarService;
import co.gov.medellin.ssti.sub.model.service.RestriccionService;
import co.gov.medellin.ssti.sub.model.service.SedeService;
import co.gov.medellin.ssti.sub.model.service.SubprogramaService;
import co.gov.medellin.ssti.sub.model.vo.AtributoVO;
import co.gov.medellin.ssti.sub.model.vo.Beneficiario_AtributoVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioOtorgadoEmpresaVO;
import co.gov.medellin.ssti.sub.model.vo.EmpresaVO;
import co.gov.medellin.ssti.sub.model.vo.SedeVO;
import co.gov.medellin.ssti.sub.model.vo.SubprogramaVO;
import co.gov.medellin.ssti.sub.paoyer.administration.exception.AdministrationUserException;
import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.UserVO;
import co.gov.medellin.ssti.sub.paoyer.administration.util.AccessControl;
import co.gov.medellin.ssti.sub.paoyer.common.exception.CommonUserException;
import co.gov.medellin.ssti.sub.paoyer.common.exception.UserException;
import co.gov.medellin.ssti.sub.web.form.IngresoDatosBeneficiosEmpresaForm;

@Component
public class IngresoDatosBeneficiosEmpresaAction extends Action {
	@Autowired
	AtributosService atributosServiceImpl;
	@Autowired
	BeneficiarioService beneficiarioServiceImpl;
	@Autowired
	BeneficioService beneficioServiceImpl;
	@Autowired
	BOTEmpresaService botEmpresaServiceImpl;
	@Autowired
	EmpresaService empresaServiceImpl;
	@Autowired
	RenovarService renovarServiceImpl;
	@Autowired
	RestriccionService restriccionServiceImpl;
	@Autowired
	SedeService sedeServiceImpl;
	@Autowired
	SubprogramaService subprogramaServiceImpl;

	/**
	 * This is the main action called from the Struts framework.
	 * 
	 * @param mapping
	 *            The ActionMapping used to select this instance.
	 * @param form
	 *            The optional ActionForm bean for this request.
	 * @param request
	 *            The HTTP Request we are processing.
	 * @param response
	 *            The HTTP Response we are processing.
	 * @return
	 * @throws java.io.IOException
	 * @throws javax.servlet.ServletException
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		HttpSession session = request.getSession();
		UserVO user = (UserVO) session.getAttribute("userInfo");

		ActionMessages messages = new ActionMessages();
		try {
			AccessControl access = new AccessControl();
			access.validateAccess(mapping, request, response);
		} catch (UserException ue) {
			messages.add("msgWarn", new ActionMessage("loginForm.message."
					+ ue.getExceptionVO().getId()));
			saveMessages(request, messages);
			if (ue.getExceptionVO().getId() == AdministrationUserException.ENDED_SESSION) {
				response.sendRedirect(request.getContextPath() + "/index.jsp");
				return null;
			} else if (ue.getExceptionVO().getId() == CommonUserException.NOT_ALLOWED_RESOURCE) {
				response.sendRedirect(request.getContextPath()
						+ "/admin/tile/invalidatedResource.jsp");
				return null;
			} else {
				return mapping.getInputForward();
			}

		}

		String terminalAddress = request.getRemoteAddr();
		String strTerminal = ("WEB=" + terminalAddress);

		IngresoDatosBeneficiosEmpresaForm formBean = (IngresoDatosBeneficiosEmpresaForm) form;

		String strCodigoEmpresa = request.getParameter("codigoEmpresa");
		String strCodigoSubprograma = request.getParameter("codigoSubprograma");
		if (strCodigoSubprograma == null || strCodigoSubprograma.equals("")) {
			strCodigoSubprograma = request.getParameter("codigoBeneficio");
		}
		String strCodigoSede = formBean.getCodigoSede();

		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dF = new SimpleDateFormat("dd/MM/yyyy");
		String strDate = dF.format(calendar.getTime());
		formBean.setFecha(strDate);
		String vigenciaBeneficio = formBean.getBot().getVigenciaBeneficio();
		String fechaMedicion = formBean.getBot().getFechaMedicion();
		Long valorBeneficio = formBean.getBot().getValorBeneficio();

		if (strCodigoEmpresa != null && !strCodigoEmpresa.equals("")) {
			formBean.setCodigoEmpresa(strCodigoEmpresa);
			EmpresaVO empresaVO = empresaServiceImpl.findEmpresaByCodigo(Long
					.valueOf(strCodigoEmpresa));
			if (empresaVO != null) {
				formBean.setEmpresaVO(empresaVO);
			}
		}

		boolean existe = botEmpresaServiceImpl.tieneBeneficio(
				Long.valueOf(formBean.getCodigoEmpresa()),
				Long.valueOf(formBean.getCodigoSubprograma()));
		// if (existe) {
		// session.setAttribute(
		// "msgdar",
		// "La empresa ya tiene el beneficio. Si el icono de renovar esta presente por favor hacer clic.");
		// return mapping.findForward("verbeneficio");
		// }

		formBean.setCodigoSubprograma(strCodigoSubprograma);

		Collection<AtributoVO> listaAtributos = atributosServiceImpl
				.findAtributosSubprograma(Long.valueOf(strCodigoSubprograma),
						"A", 0);
		Collection<SedeVO> cSedes = sedeServiceImpl.findTotalSedebyUser(
				user.getCode(), Long.valueOf(strCodigoSubprograma),
				user.getUserGroupName(), user.getCodeArea());

		if (cSedes != null) {
			if (!cSedes.isEmpty()) {
				System.out.println(cSedes.size() + ",csedes");
				formBean.setSedes(cSedes);
			}
		}
		SubprogramaVO criteria = new SubprogramaVO();
		criteria.setCode(Long.valueOf(strCodigoSubprograma));
		Collection<SubprogramaVO> subprogramas;
		try {
			subprogramas = subprogramaServiceImpl
					.findSubprogramaByCriteria(criteria);
			if (subprogramas != null && !subprogramas.isEmpty()) {
				formBean.setSubprogramaVO((SubprogramaVO) subprogramas
						.iterator().next());
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

		formBean.setListaAtributos(listaAtributos);

		/*
		 * Guardar el beneficio.
		 */
		if (formBean.getOperacion().equals(Utility.OP_GUARDAR)) {
			List<AtributoVO> lAtributo = (List<AtributoVO>) formBean
					.getListaAtributos();
			List<String> lError = new LinkedList<String>();
			List<Beneficiario_AtributoVO> lInsertar = new LinkedList<Beneficiario_AtributoVO>();
			List<AtributoVO> lAtriNoRestric = new LinkedList<AtributoVO>();
			List<AtributoVO> lAtriAlerta = new LinkedList<AtributoVO>();
			List<Beneficiario_AtributoVO> lInsertTercero = new LinkedList<Beneficiario_AtributoVO>();

			// String CodMaxBenefOtor = "";

			int tamanolatri = lAtributo.size();

			String variable = "";
			String tipodato = "";
			// String tipoatri = "";
			// String codatri = "";
			int compara1 = 0;
			int compara2 = 0;

			// fecha del beneficio
			String strDateBenefit = (String) request.getParameter("date");
			session.setAttribute("DateBenefit", strDateBenefit);
			// Fin del proceso

			Iterator<AtributoVO> it = lAtributo.iterator();
			while (it.hasNext()) {
				AtributoVO atri = it.next();
				String codigo = atri.getCodatributo();
				String obtenercod = "Atri" + codigo;
				String obligacion = atri.getObligatorio();

				if (obligacion.equals("S")) {
					compara1++;
					String obCodVeri = (String) request
							.getParameter(obtenercod);
					if (!obCodVeri.equals("")) {
						compara2++;
					} else {
						String NomError = atri.getEtiqueta();
						lError.add(NomError);
					}
				}
			}

			// proceso para validar los campos con las restricciones
			if (compara1 == compara2) {
				String obtercero = request.getParameter("tercero");

				if (obtercero != null) {
					for (int i = 0; i < tamanolatri; i++) {
						Beneficiario_AtributoVO objinsettercero = new Beneficiario_AtributoVO();
						AtributoVO atritercero = lAtributo.get(i);

						String strCodiAtri = atritercero.getCodatributo();
						// String strCodiRest = atritercero.getRestriccion();
						String strTipoAtri = atritercero.getTipoatributo();
						// String strNombre = atritercero.getNombre();
						tipodato = atritercero.getTipodato();
						variable = request.getParameter("Atri"
								+ atritercero.getCodatributo());

						if (strTipoAtri.equals("R")) {
							objinsettercero.setVariable(variable);
							objinsettercero.setTipodato(tipodato);
							objinsettercero.setCodigoatributo(strCodiAtri);
							objinsettercero
									.setCodbeneficiario(strCodigoEmpresa);
							objinsettercero.setTipoatributo(strTipoAtri);
							lInsertar.add(objinsettercero);
						} else {
							objinsettercero.setVariable(variable);
							objinsettercero.setTipodato(tipodato);
							objinsettercero.setCodigoatributo(strCodiAtri);
							objinsettercero.setTipoatributo(strTipoAtri);
							lInsertar.add(objinsettercero);
						}

						objinsettercero.setVariable(variable);
						objinsettercero.setTipodato(tipodato);
						objinsettercero.setCodigoatributo(strCodiAtri);
						objinsettercero.setCodbeneficiario(strCodigoEmpresa);
						objinsettercero.setTipoatributo(strTipoAtri);
						lInsertTercero.add(objinsettercero);
					}
					session.setAttribute("listatercero", lInsertTercero);

				} else {
					for (int i = 0; i < tamanolatri; i++) {

						Beneficiario_AtributoVO objBenAtriVO = new Beneficiario_AtributoVO();
						AtributoVO atrirestri = (AtributoVO) lAtributo.get(i);
						String strCodiAtri = atrirestri.getCodatributo();
						String strCodiRest = atrirestri.getRestriccion();
						String strTipoAtri = atrirestri.getTipoatributo();
						// String strNombre = atrirestri.getNombre();
						tipodato = atrirestri.getTipodato();

						variable = request.getParameter("Atri"
								+ atrirestri.getCodatributo());
						System.err.println("[GuardarBeneficiosAction]" + "Atri"
								+ atrirestri.getCodatributo() + "::="
								+ variable);

						if (strCodiRest != null && !strCodiRest.isEmpty()) {
							try {
								String ArrRest[] = restriccionServiceImpl
										.validarRestriccion(strCodiAtri,
												strCodiRest, variable, tipodato);
								if (ArrRest[0].equals("N")) {
									if (ArrRest[1].equals("true")) {

										session.setAttribute("mensajes", "1");

										if (strTipoAtri.equals("R")) {
											objBenAtriVO.setVariable(variable);
											objBenAtriVO.setTipodato(tipodato);
											objBenAtriVO
													.setCodigoatributo(strCodiAtri);
											objBenAtriVO
													.setCodbeneficiario(strCodigoEmpresa);
											objBenAtriVO
													.setTipoatributo(strTipoAtri);
											lInsertar.add(objBenAtriVO);

										} else {
											objBenAtriVO.setVariable(variable);
											objBenAtriVO.setTipodato(tipodato);
											objBenAtriVO
													.setCodigoatributo(strCodiAtri);
											objBenAtriVO
													.setTipoatributo(strTipoAtri);
											lInsertar.add(objBenAtriVO);

										}
									} else {
										session.setAttribute("mensajes", "2");
										atrirestri.setDescrest(ArrRest[2]);
										lAtriNoRestric.add(atrirestri);
									}
								} else {
									if (ArrRest[1].equals("false")) {
										session.setAttribute("mensajes", "3");
										atrirestri.setDescrest(ArrRest[2]);
										lAtriAlerta.add(atrirestri);
									}
									if (strTipoAtri.equals("R")) {
										objBenAtriVO.setVariable(variable);
										objBenAtriVO.setTipodato(tipodato);
										objBenAtriVO
												.setCodigoatributo(strCodiAtri);
										objBenAtriVO
												.setCodbeneficiario(strCodigoEmpresa);
										objBenAtriVO
												.setTipoatributo(strTipoAtri);
										lInsertar.add(objBenAtriVO);
									} else {
										objBenAtriVO.setVariable(variable);
										objBenAtriVO.setTipodato(tipodato);
										objBenAtriVO
												.setCodigoatributo(strCodiAtri);
										objBenAtriVO
												.setTipoatributo(strTipoAtri);
										lInsertar.add(objBenAtriVO);
									}
								}
							} catch (DAOException e) {
								SUBException.logDebugError("", e);
							}
						} else {
							if (strTipoAtri.equals("R")) {
								objBenAtriVO.setVariable(variable);
								objBenAtriVO.setTipodato(tipodato);
								objBenAtriVO.setCodigoatributo(strCodiAtri);
								objBenAtriVO
										.setCodbeneficiario(strCodigoEmpresa);
								objBenAtriVO.setTipoatributo(strTipoAtri);
								lInsertar.add(objBenAtriVO);
							} else {
								objBenAtriVO.setVariable(variable);
								objBenAtriVO.setTipodato(tipodato);
								objBenAtriVO.setCodigoatributo(strCodiAtri);
								objBenAtriVO.setTipoatributo(strTipoAtri);
								lInsertar.add(objBenAtriVO);
							}
						}

					}
				}

				if (lAtriNoRestric.size() > 0) {
					session.setAttribute("listanorestric", lAtriNoRestric);
				} else {
					session.removeAttribute("listanorestric");
				}

				if (lAtriAlerta.size() > 0) {
					session.setAttribute("listaalerta", lAtriAlerta);
				} else {
					session.removeAttribute("listaalerta");
				}
				session.setAttribute("mensaje", "1");
				session.setAttribute("listainsetar", lInsertar);

			} else {

				int tama = lError.size();
				String strTamaError = String.valueOf(tama);
				if (lAtriNoRestric.size() > 0) {
					session.setAttribute("listanorestric", lAtriNoRestric);
				} else {
					session.removeAttribute("listanorestric");
				}

				if (lAtriAlerta.size() > 0) {
					session.setAttribute("listaalerta", lAtriAlerta);
				} else {
					session.removeAttribute("listaalerta");
				}
				session.setAttribute("ListaErrores", lError);
				session.setAttribute("tamanoError", strTamaError);
				session.setAttribute("mensaje", "2");
			}
			if ((lAtriAlerta.size() > 0) || (lAtriNoRestric.size() > 0)
					|| lError.size() > 0) {
				return mapping.findForward("success");
			}

			SubprogramaVO codigosub = new SubprogramaVO();
			String strCodigoSubpro = formBean.getCodigoSubprograma();

			codigosub.setCode(new Long(strCodigoSubpro));

			try {

				List<SubprogramaVO> lNom = (List<SubprogramaVO>) subprogramaServiceImpl
						.findSubprogramaByCriteria(codigosub, user.getCode(),
								user.getUserGroupName(), user.getCodeArea());

				codigosub = (SubprogramaVO) lNom.get(0);

				cSedes = formBean.getSedes();

				if ((Object) cSedes != null) {
					if (cSedes.size() > 0)
						session.setAttribute("ListaSede", cSedes);
				}

				try {
					SubprogramaVO subproVO = new SubprogramaVO();
					subproVO.setCode(new Long(strCodigoSubpro));

					List<SubprogramaVO> subpro = (List<SubprogramaVO>) subprogramaServiceImpl
							.findSubprogramaByCriteria(codigosub,
									user.getCode(), user.getUserGroupName(),
									user.getCodeArea());
					if (subpro != null && subpro.size() > 0) {
						subproVO = (SubprogramaVO) subpro.get(0);

					}

				} catch (DAOException e) {
					SUBException.logDebugError("", e);
				}

				// Proceso para obtener el valor del beneficio
				String strCostBene = null;

				strCostBene = beneficioServiceImpl.findCostoBeneficio(new Long(
						strCodigoSubpro));

				if (strCostBene != null) {
					request.setAttribute("CostBene", strCostBene);
				}
				// Fin del proceso

			} catch (Exception e) {
				SUBException.logDebugError("", e);
			}

			// Guardar..

			List<Beneficiario_AtributoVO> lInsert = new LinkedList<Beneficiario_AtributoVO>();
			String strTercero = "";

			boolean disponibilidad = true;

			// if (!existe) {
			String strCostBenefit = formBean.getSubprogramaVO()
					.getValorUnitarioBeneficio();
			// Adicion tipo beneficio
			String strTypeBenefit = formBean.getSubprogramaVO().getNombre();

			List<Beneficiario_AtributoVO> obTercero = lInsertTercero;
			List<Beneficiario_AtributoVO> obListaInsert = lInsertar;

			if (obTercero == null || obTercero.isEmpty()) {
				lInsert = obListaInsert;
			} else {
				lInsert = obTercero;
				strTercero = (String) session.getAttribute("Tercero");
			}

			if (obListaInsert != null) {
				try {
					Long loCodigoSede = Long.valueOf(strCodigoSede);
					Long loCodigoSubp = Long.valueOf(strCodigoSubpro);
					Long loCodigoBenefi = Long.valueOf(strCodigoEmpresa);

					long totaldias = 1;

					// Proceso para determinar si hay beneficios
					int disponible = beneficioServiceImpl.findDisponibilidad(
							new Long(strCodigoSede), new Long(strCodigoSubpro));
					if (totaldias > disponible) {
						disponibilidad = false;
					}
					// Fin del proceso

					if (disponibilidad) {
						// Proceso para desabilitar los beneficios otorgados
						// anteriores
						// TODO: investigar q deberia hacer esto.
						// renovarServiceImpl.findBeneOtorDeshabilitar(
						// new Long(strCodigoSubpro),
						// Long.valueOf(strCodigoEmpresa),
						// Long.valueOf(strCodigoSede));
						// fin del proceso

						// Proceso para insertar en beneficio otorgado

						BeneficioOtorgadoEmpresaVO beneficioOtorgadoEmpresaVO = new BeneficioOtorgadoEmpresaVO();
						beneficioOtorgadoEmpresaVO.setSedeCodigo(loCodigoSede);
						beneficioOtorgadoEmpresaVO.setSbprCodigo(loCodigoSubp);
						beneficioOtorgadoEmpresaVO.setEmpCodigo(loCodigoBenefi);
						beneficioOtorgadoEmpresaVO
								.setFechaBeneficio(strDateBenefit);
						beneficioOtorgadoEmpresaVO
								.setTipoBeneficio(strTypeBenefit);
						beneficioOtorgadoEmpresaVO.setUsuarioCrea(user
								.getName());
						beneficioOtorgadoEmpresaVO.setUsuarioModifica(user
								.getName());
						beneficioOtorgadoEmpresaVO.setTerminalCrea(strTerminal);
						beneficioOtorgadoEmpresaVO
								.setTerminalModifica(strTerminal);
						beneficioOtorgadoEmpresaVO
								.setVigenciaBeneficio(vigenciaBeneficio);
						beneficioOtorgadoEmpresaVO
								.setFechaMedicion(fechaMedicion);
						beneficioOtorgadoEmpresaVO.setValorBeneficio(Long
								.valueOf(valorBeneficio));

						boolean insert = botEmpresaServiceImpl
								.otorgarBeneficio(beneficioOtorgadoEmpresaVO,
										lInsert);

						session.setAttribute("msg", "1");
						ActionForward actionRedirect = new ActionForward(
								mapping.findForward("ir").getName(), mapping
										.findForward("ir").getPath()
										+ "?codigoEmpresa="
										+ formBean.getCodigoEmpresa(), true);
						return actionRedirect;
					} else {
						session.setAttribute("msgdis",
								"No hay beneficios disponibles en la sede seleccionada.");
					}
				} catch (Exception e) {
					SUBException.logDebugError("", e);
				}
			}

			// } else {
			// session.setAttribute("msg", "2");
			// }
			return mapping.findForward("success");

		}

		return mapping.findForward("success");
	}
}
